home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 25 / AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso / Updates / Hardware / FreeWheel / Scroll.c < prev    next >
C/C++ Source or Header  |  2000-03-12  |  5KB  |  232 lines

  1. #include <stdio.h>
  2.  
  3. #include <exec/types.h>
  4.  
  5. #include <intuition/intuitionbase.h>
  6. #include <intuition/intuition.h>
  7. #include <intuition/screens.h>
  8. #include <graphics/clip.h>
  9. #include <devices/inputevent.h>
  10.  
  11. #include <clib/exec_protos.h>
  12. #include <clib/intuition_protos.h>
  13. #include <clib/layers_protos.h>
  14.  
  15. #include "WheelMouse.h"
  16.  
  17. #include "Scroll.h"
  18. #include "RawKey.h"
  19.  
  20. extern struct IntuitionBase *IntuitionBase;
  21.  
  22. struct Window *WindowUnderPointer();
  23.  
  24. /* With any luck this will fix reported CyberGuard hits with MUI programs. */
  25. struct
  26. {
  27.   char a,b,c,d;
  28. } DeadKeyData;
  29.  
  30.  
  31. void SendIDCMP(struct WheelMouseContext *wmc,int class,int code,int qualifier,struct IntuiMessage *im)
  32. {
  33.   struct Window *win=wmc->Window;
  34.   struct Gadget *gg=wmc->Gadget;
  35.   im->IDCMPWindow=win;
  36.   if(class==IDCMP_RAWKEY)
  37.     im->IAddress=&DeadKeyData;
  38.   else
  39.     im->IAddress=gg;
  40.   im->Class=class;
  41.   im->Code=code;
  42.   im->Qualifier=qualifier;
  43.   im->MouseX=win->MouseX;
  44.   im->MouseY=win->MouseY;
  45.   im->ExecMessage.mn_ReplyPort=wmc->ReplyPort;
  46.   im->Seconds=IntuitionBase->Seconds; im->Micros=IntuitionBase->Micros;
  47.   im->SpecialLink=NULL;
  48.   PutMsg(win->UserPort,(struct Message *)im);
  49. }
  50.  
  51.  
  52. void NudgePropGadget(struct Gadget *gg,struct Window *win,int axis,int direction)
  53. {
  54.   struct PropInfo *pi=(struct PropInfo *)gg->SpecialInfo;
  55.  
  56.   long current,offset;
  57.  
  58.   if(axis&FREEVERT)
  59.   {
  60.     current=pi->VertPot;
  61.     offset=pi->VPotRes;
  62.     current+=(direction*offset)/3;
  63.     if(current<0) current=0;
  64.     if(current>0xffff) current=0xffff;
  65.     pi->VertPot=current;
  66.   }
  67.  
  68.   if(axis&FREEHORIZ)
  69.   {
  70.     current=pi->HorizPot;
  71.     offset=pi->HPotRes;
  72.     current+=(5*(direction*offset))/8;
  73.     if(current<0) current=0;
  74.     if(current>0xffff) current=0xffff;
  75.     pi->HorizPot=current;
  76.   }
  77.  
  78. }
  79.  
  80.  
  81. struct Gadget *FindPropGadget(struct Window *win,long type)
  82. {
  83.   struct Gadget *gg=win->FirstGadget,*bestgadget=NULL;
  84.   int gx,gy,gt,gl,gw,gh,dd,distance=32767;
  85.   while(gg)
  86.   {
  87.     if((gg->GadgetType>YP_GTYPEMASK)==GTYP_PROPGADGET)
  88.     {
  89.       struct PropInfo *pi=(struct PropInfo *)gg->SpecialInfo;
  90.       if(pi)
  91.       {
  92.         if(pi->Flags&type)
  93.         {
  94.           dd=32767;
  95.  
  96.           gl=gg->LeftEdge; gt=gg->TopEdge;
  97.           gw=gg->Width; gh=gg->Height;
  98.           if(gg->Flags&GFLG_RELRIGHT)
  99.             gl+=win->Width;
  100.           if(gg->Flags&GFLG_RELBOTTOM)
  101.             gt+=win->Height;
  102.           if(gg->Flags&GFLG_RELWIDTH)
  103.             gw+=win->Width;
  104.           if(gg->Flags&GFLG_RELHEIGHT)
  105.             gh+=win->Height;
  106.  
  107.           if(pi->Flags&FREEVERT)
  108.           {
  109.             gx=gl+gw;
  110.  
  111.             dd=gx-win->MouseX;
  112.             if(dd<0)
  113.               dd=-dd+win->Width; /* bias to left of scrollbar */
  114.             gy=(gt+gh)-win->MouseY;
  115.             if((gt-win->MouseY)*(gt-win->MouseY)<(gy*gy))
  116.               gy=gt-win->MouseY;
  117.             if(gy<0)
  118.               gy=-gy;
  119.             dd+=gy;
  120.           }
  121.           if(pi->Flags&FREEHORIZ)
  122.           {
  123.             gx=win->MouseX-gl;
  124.             gy=win->MouseY-gt;
  125.             if((gx>=-2)&&(gy>=-2)&&(gx<=(gw+2))&&(gy<=(gh+2)))
  126.               dd=1;
  127.           }
  128.           if(dd<0) dd=-dd;
  129.           if(dd<distance)
  130.           {
  131.             distance=dd;
  132.             bestgadget=gg;
  133.           }
  134.         }
  135.       }
  136.     }
  137.     gg=gg->NextGadget;
  138.   }
  139.   return(bestgadget);
  140. }
  141.  
  142.  
  143. int DoScroll(struct WheelMouseContext *wmc,int axis,int direction)
  144. {
  145.   struct Window *win;
  146.   Forbid();
  147.   if(wmc->WindowMode==OverWindow)
  148.     win=wmc->Window=WindowUnderPointer();
  149.   else
  150.     win=wmc->Window=IntuitionBase->ActiveWindow;
  151.   if(!(win))
  152.     return(direction);
  153.   wmc->Gadget=FindPropGadget(win,axis);
  154.   if((!(wmc->Gadget))&&(wmc->WindowMode==OverWindow)&&((win->IDCMPFlags&IDCMP_RAWKEY)==0))
  155.   {
  156.     if(!(win=wmc->Window=IntuitionBase->ActiveWindow))
  157.       return(direction);
  158.     wmc->Gadget=FindPropGadget(win,axis);
  159.   }
  160.  
  161.   if(wmc->Gadget)
  162.   {
  163.     NudgePropGadget(wmc->Gadget,win,axis,direction);
  164.     SendIDCMP(wmc,IDCMP_GADGETDOWN,0,0,&wmc->Msg1.eim_IntuiMessage);
  165.     SendIDCMP(wmc,IDCMP_GADGETUP,0,0,&wmc->Msg2.eim_IntuiMessage);
  166.     RefreshGList(wmc->Gadget,wmc->Window,NULL,1);
  167.     Permit();
  168.     WaitPort(wmc->ReplyPort);
  169.     GetMsg(wmc->ReplyPort);
  170.     WaitPort(wmc->ReplyPort);
  171.     GetMsg(wmc->ReplyPort);
  172.     return(direction);
  173.   }
  174.   else if(win->IDCMPFlags&IDCMP_RAWKEY)
  175.   {
  176.     int code,c,d,q=0;
  177.     d=direction;
  178.     if(d>0)
  179.       if(axis&FREEVERT)
  180.         code=RK_Down;
  181.       else
  182.         code=RK_Right;
  183.     else
  184.     {
  185.       if(axis&FREEVERT)
  186.         code=RK_Up;
  187.       else
  188.         code=RK_Left;
  189.       d=-d;
  190.     }
  191.     if(d>1)
  192.       q=IEQUALIFIER_LSHIFT;
  193.     SendIDCMP(wmc,IDCMP_RAWKEY,code,q,&wmc->Msg1.eim_IntuiMessage);
  194.     SendIDCMP(wmc,IDCMP_RAWKEY,code|IECODE_UP_PREFIX,q,&wmc->Msg2.eim_IntuiMessage);
  195.     Permit();
  196.     WaitPort(wmc->ReplyPort);
  197.     GetMsg(wmc->ReplyPort);
  198.     WaitPort(wmc->ReplyPort);
  199.     GetMsg(wmc->ReplyPort);
  200.     return(direction);
  201.   }
  202.   Permit();
  203.   return(direction);
  204. }
  205.  
  206.  
  207. struct Window *WindowUnderPointer()
  208. {
  209.   int x,y;
  210.   unsigned long lock;
  211.   struct Window *win=NULL;
  212.   struct Screen *scr;
  213.   struct Layer *layer;
  214.  
  215.   scr=IntuitionBase->FirstScreen;
  216.   do
  217.   {
  218.     x=scr->MouseX; y=scr->MouseY;
  219.     if((x<0) || (y<0))
  220.       scr=scr->NextScreen;
  221.   } while((scr!=NULL) && ((x<0)||(y<0)));
  222.  
  223.   if(!scr)
  224.     return(NULL);
  225.  
  226.   layer=WhichLayer(&scr->LayerInfo,x,y);
  227.   if(layer)
  228.     win=layer->Window;
  229.   return(win);
  230. }
  231.  
  232.